package at.ac.univie.zsu.aguataplan.ui.template;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;

import org.jdesktop.swingx.JXList;

import at.ac.univie.zsu.aguataplan.property.GeneralProperties;
import at.ac.univie.zsu.aguataplan.property.I18nProperties;
import at.ac.univie.zsu.aguataplan.ui.UIConstants;

/**
 * @author gerry
 * 
 */
public class RelationEntryPanel extends JPanel implements UIConstants {

	private static final long serialVersionUID = 1L;

	private JDialog dialogParent;
	private GeneralProperties generalProperties;
	private I18nProperties i18nProp;
	private IDialogRelationEntry iDialogRelationEntry;

	private JXList list1;
	private JScrollPane list1Scroll;
	private JXList listRelation;
	private JScrollPane listRelationScroll;
	private JXList list2;
	private JScrollPane list2Scroll;

	private DefaultListModel listModel1;
	private DefaultListModel listModelRelation;
	private DefaultListModel listModel2;

	private JButton addBtn;
	private JButton deleteBtn;

	private List<RelationEntryPanel> sibling;

	// ----------------------------------------------------
	// CONSTRUCTOR
	// ----------------------------------------------------

	public RelationEntryPanel(JDialog dialogParent, GeneralProperties generalProperties,
			IDialogRelationEntry iDialogRelationEntry) {

		this.dialogParent = dialogParent;
		this.generalProperties = generalProperties;
		this.i18nProp = generalProperties.getI18nProperties();
		this.iDialogRelationEntry = iDialogRelationEntry;

		this.setLayout(null);

		sibling = new ArrayList<RelationEntryPanel>();

	}

	// ----------------------------------------------------
	// METHODS
	// ----------------------------------------------------

	public void addSibling(RelationEntryPanel rep) {
		this.sibling.add(rep);
	}

	public void init(String borderName, int sizeY) {
		this.setBorder(javax.swing.BorderFactory.createTitledBorder(borderName));

		list1Scroll = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
				JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		list1 = new JXList();
		list1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		list1.setModel(getListModel1());
		list1Scroll.setSize(150, sizeY - 70);
		list1Scroll.setLocation(10, 20);
		list1Scroll.getViewport().add(list1);
		this.add(list1Scroll);

		list2Scroll = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
				JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		list2 = new JXList();
		list2.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		list2.setModel(getListModel2());
		list2Scroll.setSize(150, sizeY - 70);
		list2Scroll.setLocation(350, 20);
		list2Scroll.getViewport().add(list2);
		this.add(list2Scroll);

		listRelationScroll = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
				JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		listRelation = new JXList();
		listRelation.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		listRelation.setModel(getListModelRelation());
		listRelationScroll.setSize(150, sizeY - 70);
		listRelationScroll.setLocation(180, 20);
		listRelationScroll.getViewport().add(listRelation);
		this.add(listRelationScroll);

		addBtn = new JButton(i18nProp.getString(ADD_BUTTON));
		addBtn.setSize(BUTTON_SIZE_X, BUTTON_SIZE_Y);
		deleteBtn = new JButton(i18nProp.getString(DELETE_BUTTON));
		deleteBtn.setSize(BUTTON_SIZE_X, BUTTON_SIZE_Y);

		addBtn.setLocation(150, sizeY - 40);
		deleteBtn.setLocation(260, sizeY - 40);

		this.add(addBtn);
		this.add(deleteBtn);

		disableButton();
		initListModel1();
		initListModel2();
		enableButton();

		// Listener
		// -------------------------------
		// click on free area
		addMouseListener(new java.awt.event.MouseAdapter() {
			public void mouseClicked(java.awt.event.MouseEvent evt) {
				cleanText();

			}
		});

		// click on list to select entry
		list1.addMouseListener(new java.awt.event.MouseAdapter() {
			public void mouseClicked(java.awt.event.MouseEvent evt) {
				Object obj = list1.getSelectedValue();
				if (obj == null) {
					return;
				}

				listModelRelation.clear();

				List<?> list = iDialogRelationEntry.select1(obj);

				if (list == null) {
					return;
				}

				initListModelRelation(list);

			}
		});

		addBtn.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				int index;
				Object o1 = null;
				Object o2 = null;
				o1 = list1.getSelectedValue();
				index = list1.getSelectedIndex();
				o2 = list2.getSelectedValue();
				if (o1 == null || o2 == null) {
					return;
				}

				boolean retVal;

				retVal = iDialogRelationEntry.add(o1, o2);

				// if (!retVal) {
				// return;
				// }

				initListModel1();
				initListModel2();

				Object o;
				list1.setSelectedIndex(index);
				o = list1.getSelectedValue();
				List<?> list = iDialogRelationEntry.select1(o);

				initListModelRelation(list);

				informSibling();

			}
		});
		deleteBtn.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {

				Object o1 = null;
				Object o2 = null;
				o1 = list1.getSelectedValue();
				o2 = listRelation.getSelectedValue();

				int index = list1.getSelectedIndex();

				if (o1 == null || o2 == null) {
					return;
				}

				boolean retVal;

				retVal = iDialogRelationEntry.delete(o1, o2);

				// if (!retVal) {
				// return;
				// }

				initListModel1();
				initListModel2();
				list1.setSelectedIndex(index);
				Object o = list1.getSelectedValue();
				List<?> list = iDialogRelationEntry.select1(o);

				initListModelRelation(list);

				informSibling();

			}
		});
		this.setSize(PANEL_SIZE_X_RELATION, sizeY);
		setVisible(true);

	}

	public void renewSibling() {
		initListModel1();
		initListModel2();
	}

	// ----------------------------------------------------
	// METHODS PRIVATE
	// ----------------------------------------------------

	private ListModel getListModel1() {

		if (listModel1 == null) {
			listModel1 = new DefaultListModel();

		}
		return listModel1;
	}

	private ListModel getListModel2() {
		if (listModel2 == null) {
			listModel2 = new DefaultListModel();
		}
		return listModel2;
	}

	private ListModel getListModelRelation() {
		if (listModelRelation == null) {
			listModelRelation = new DefaultListModel();
		}
		return listModelRelation;
	}

	private void cleanText() {

		// clean list selection
		list1.clearSelection();
		listRelation.clearSelection();
		list2.clearSelection();

		listModelRelation.clear();

	}

	private void initListModel1() {
		if (iDialogRelationEntry.init1() == null) {
			return;
		}

		listModel1.clear();
		listModelRelation.clear();

		for (Object o : iDialogRelationEntry.init1()) {
			listModel1.addElement(o);
		}

	}

	private void initListModel2() {
		if (iDialogRelationEntry.init2() == null) {
			return;
		}

		listModel2.clear();

		for (Object o : iDialogRelationEntry.init2()) {
			listModel2.addElement(o);
		}

	}

	private void initListModelRelation(List<?> list) {
		listModelRelation.clear();

		for (int i = 0; i < list.size(); i++) {
			listModelRelation.addElement(list.get(i));
		}

	}

	private void disableButton() {
		// disable buttons
		addBtn.setEnabled(false);
		deleteBtn.setEnabled(false);

		// disable list
		list1.setEnabled(false);
		list2.setEnabled(false);

	}

	private void enableButton() {
		// enable buttons
		addBtn.setEnabled(true);
		deleteBtn.setEnabled(true);

		// disable list
		list1.setEnabled(true);
		list2.setEnabled(true);

	}

	private void informSibling() {
		for (RelationEntryPanel s : sibling) {
			s.renewSibling();
		}
	}
}
